15장 let,const 키워드와 블록레벨스코프


var로 선언한 변수의 문제점

  1. 변수 중복 선언 허용
  2. 함수 레벨 스코프
    var은 함수의 코드블록만 지역 스코프로 인정해서 if문,for문 등에서 선언한 변수는 전역변수가 된다.
    ⇒ 전역변수가 남발하게 되고 전역변수 중복 선언되기 쉬움
  3. 변수 호이스팅
    변수 호이스팅에 의해서 변수 선언문 이전에 변수 참조해도 에러 발생되지 않음
    ⇒ 가독성 떨어지고 오류 가능성

let 키워드

  1. 변수 중복 선언 금지
  2. 블록 레벨 스코프
  3. 변수 호이스팅

변수 호이스팅

let 키워드도 var 처럼 변수 호이스팅이 발생하지만, 발생하지 않는 것처럼 동작한다.

console.log(foo); // ReferenceError: foo is not defined
let foo;

var과 달리 let은 선언문 이전에 참조하면 에러가 발생

왜 let은 선언문 이전에 참조하면 에러가 발생할까?

var 키워드는 암묵적으로 선언 단계초기화 단계 가 한번에 진행

선언 단계에서 스코프( 실행 컨텍스트의 렉시컬 환경)에 식별자 등록해서 JS 엔진이 변수의 존재 알게하고, 초기화 단계에서 undefined 로 변수 초기화

// var 키워드로 선언한 변수는 런타임 이전에 선언 단계와 초기화 단계가 실행된다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 있다.
console.log(foo); // undefined

var foo;
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

Untitled 17.png|Untitled 17.png

let의 경우
선언 단계초기화 단계 가 분리되어 진행
스코프 시작 지점부터 초기화 시작 지점까지 변수 참조할 수 없는 구간일시적 사각지대(TDZ) 가 존재.
따라서 선언문에서 초기화 하기 전에 변수를 참조하면 에러가 발생한다.

// 런타임 이전에 선언 단계가 실행된다. 아직 변수가 초기화되지 않았다.
// 초기화 이전의 일시적 사각 지대에서는 변수를 참조할 수 없다.
console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

Untitled 1 10.png|Untitled 1 10.png

그럼 그냥 변수 호이스팅 발생 안하는 거랑 마찬가지 아니야?

let foo = 1; // 전역 변수
{
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
let foo = 2; // 지역 변수

위 코드에서 두번째 foo가 스코프 내에서 호이스팅되어서 console.log(foo) 했을 때 전역 변수가 호출되지 않은 모습.

const 키워드

const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화 해야함.
let 처럼 변수 호이스팅이 일어나지 않은 것 처럼 동작
재할당이 금지되고 재할당 시 오류 발생
일반적으로 이름을 대문자로 선언

const 와 객체

const 변수는 재할당이 불가능하다 → 원시값은 변경 불가능한 값이므로 변경X
객체의 경우 값의 변경이 가능함 ⇒ const 변수에 할당된 객체 값 변경 가능

const person = {
  name: 'Lee'
};

// 객체는 변경 가능한 값이다. 따라서 재할당없이 변경이 가능하다.
person.name = 'Kim';

console.log(person); // {name: "Kim"}

var vs. let vs. const

기본적으로 const 사용하고 재할당 필요할 경우에 let 을 사용하는 것이 좋다.
객체는 재할당하는 경우가 드믈어서 일단 const 사용하는게 좋다.

reference